<?php

namespace app\service\DataCollect;

use app\library\DataReturn;
use Exception;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;

/**
 * 数据采集抽象服务
 */
abstract class AbstractDataCollectService
{
    /**
     * @var Client
     */
    protected Client $httpClient;

    /**
     * @var array
     */
    protected array $httpClientConfig = [];

    /**
     * @var ResponseInterface
     */
    protected ResponseInterface $httpResponse;

    /**
     * @var string 错误信息
     */
    protected string $errorMessage = '';

    /**
     * @var numeric 错误编码
     */
    protected $errorCode;

    /**
     * 构造方法
     */
    public function __construct()
    {
        $this->_selfInit();
        $this->_init();
    }

    /**
     * 自身初始化
     * @return void
     */
    private function _selfInit()
    {
        $this->httpClientConfig = $this->initHttpClientConfig();
        $this->httpClient = new Client(
            $this->httpClientConfig
        );
    }

    /**
     * 子类初始化
     * @return void
     */
    protected function _init()
    {
    }

    /**
     * 初始化Http Client 配置方法
     * @return array
     */
    abstract protected function initHttpClientConfig(): array;

    /**
     * 定义API请求方法
     * @param string $methodOrUrl
     * @param array $param
     * @param string $resquestMethod
     * @return mixed
     */
    abstract public function requestApi(string $methodOrUrl, array $param, string $resquestMethod): DataReturn;

    /**
     * api错误返回处理
     * @param $bodyContents
     * @return mixed
     */
    abstract protected function apiResponseError($bodyContents);

    /**
     * 统一处理返回值
     * @param ResponseInterface $response
     * @param bool $jsonDecode
     * @return DataReturn
     */
    protected function responseContent(ResponseInterface $response, bool $jsonDecode = true): DataReturn
    {
        $this->httpResponse = $response;
        try {
            $statusCode = $response->getStatusCode();
            if ($statusCode !== 200) {
                makeException("http code not 200");
            }
            $bodyContents = $response->getBody()->getContents();
            if ($jsonDecode) {
                $bodyContents = json_decode($bodyContents, true);
                if (is_null($bodyContents)) {
                    makeException("json decode null");
                }
            }
            $this->apiResponseError($bodyContents);
            return dataReturn($bodyContents);
        } catch (Exception $e) {
            return $this->setError($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 设置错误
     * @param $errorMessage
     * @param $errorCode
     * @return DataReturn
     */
    protected function setError($errorMessage, $errorCode): DataReturn
    {
        $class = get_called_class();
        $this->errorMessage = $class . " error msg:" . $errorMessage;
        $this->errorCode = $class . " error code:" . $errorCode;
        $errorMessage = implode(" && ", [$class, $errorMessage, $errorCode]);
        return dataErrorReturn($errorMessage);
    }


}